﻿using System;
using System.IO;
using Microsoft.Dss.Core;
using Microsoft.Win32;

namespace CI.Utils
{
    /// <summary>
    /// Robotics Folder class that handes find etc
    /// </summary>
    public static class RoboticsConfig
    {
        /// <summary>
        /// Scenario files registered in environment
        /// </summary>
        public static readonly string[] ScenarioFiles = new[]
                                                   {
                                                       "Survival of the Fattest.Scenario.xml",
                                                       "Clean my house.Scenario.xml",
                                                       "Genesis Clean my house.Scenario.xml"
                                                   };

        private static readonly SimEnv SimEnv = SimEnv.Instance;

        private const string SearchFile = @"\dsshost32.exe";

        // todo : testing install from any folder but set the runnng robotics path
        /// <summary>
        /// Find the robotics folders
        /// </summary>
        /// <returns></returns>
        public static string FindRoboticsFolders()
        {
            const string expressPath = @"Microsoft Robotics Dev Studio 2008 R3\bin";
            var searchFolders = new[] 
            { 
                                          Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"),expressPath), 
                                          Path.Combine("C:",expressPath), 
                                          Path.Combine("D:",expressPath)
            };

#if DEBUG
            SimEnv.TraceLogger.LogDebug("Searching for Robotics Folder in : ");
            foreach (string folder in searchFolders)
            {
                SimEnv.TraceLogger.LogDebug(folder);
            }
#endif

            foreach (string folder in searchFolders)
            {
                if (System.IO.File.Exists(folder + SearchFile))
                {
                    SimEnv.TraceLogger.LogDebug("Robotics Folder found: " + folder + SearchFile);
                    return folder;
                }
            }


            SimEnv.TraceLogger.LogWarn("NO Robotics Folder found! - using registry search");
            return SearchRegistryRoboticsFolder();
        }

        /// <summary>
        /// search the registry for the robotics folder
        /// </summary>
        /// <returns></returns>
        public static string SearchRegistryRoboticsFolder()
        {
            SimEnv.TraceLogger.LogDebug("SearchRegistryRoboticsFolder - Start ");

            // todo : refactor to determine if 64 or 32bit os

            // if 32 bit
            var result = SearchRegistry(@"SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs\") ??
                            SearchRegistry(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\SharedDLLs\");

            // if not found then could be 64 bit

            if (result == null)
            {
                SimEnv.TraceLogger.LogWarn("NO Robotics Folder registry found!");
            }
            else
            {
                SimEnv.TraceLogger.LogDebug("Robotics Folder found: " + result);
            }
            SimEnv.TraceLogger.LogDebug("SearchRegistryRoboticsFolder - Finish ");

            return result;

        }

        /// <summary>
        /// searches registry for value
        /// </summary>
        /// <param name="registryLocation"></param>
        /// <returns></returns>
        private static string SearchRegistry(string registryLocation)
        {
            string result = null;

            var oKey = Registry.LocalMachine.OpenSubKey(registryLocation, false);
            if (oKey != null)
            {
                // get a list of values
                var names = oKey.GetValueNames();

                // search through the values
                foreach (string name in names)
                {
                    if (name.ToLower().Contains(SearchFile.ToLower()))
                    {
                        result = name.ToLower().Replace(SearchFile.ToLower(), "");
                        break;
                    }
                }
            }

            return result;
        }

        /// <summary>
        /// copy the scenario files in my documents
        /// </summary>
        public static void CopyScenarioFiles()
        {
            foreach (string file in ScenarioFiles)
            {
                // if it exists in the current folder and not my documents
                if ((File.Exists(Environment.CurrentDirectory + @"\XML\" + file)) && (!File.Exists(BuildFilePath(file))))
                {
                    SimEnv.TraceLogger.LogDebug("Copying file: " + file);
                    File.Copy(Environment.CurrentDirectory + @"\XML\" + file, BuildFilePath(file));
                }
                else
                {
                    SimEnv.TraceLogger.LogDebug("File Not Copied: " + file);
                }
            }

        }

        /// <summary>
        /// Delete the scenario files in my documents
        /// </summary>
        public static void DeleteScenarioFiles()
        {
            foreach (string file in ScenarioFiles)
            {
                // if it exists in my documents
                if (File.Exists(BuildFilePath(file)))
                {
                    SimEnv.TraceLogger.LogDebug("Deleteing file: " + file);
                    File.Delete(BuildFilePath(file));
                }
            }

        }

        private static string BuildFilePath(string file)
        {
            return Path.Combine(ResourceFolders.UsersResourceFolder(), file);
        }

        /// <summary>
        /// Loads dss config
        /// </summary>
        /// <returns></returns>
        public static DssRuntimeConfiguration LoadDssConfig(int basePort)
        {
            var dssConfig = new DssRuntimeConfiguration
                                {
                                    PublicHttpPort = basePort,
                                    PublicTcpPort = basePort + 1,
                                    HostRootDir = FindRoboticsFolders()
                                };

            return dssConfig;
        }
    }
}


